package multidraw.model;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.Vector;

public class OvalShape extends TwoEndShape implements TwoEndBoundaryShape {
	double leftX;
	double topY;
	double width;
	double height;	
	
	private boolean isFilled;
		
	public OvalShape(double leftX, double topY, double width, double height, 
			Color c, long id) {
		this.leftX = leftX;
		this.topY = topY;
		this.width = width;
		this.height = height;
		this.penColor = c;
		this.isFilled = false;
		this.shapeID = id;
	}

	

	public void draw(Graphics g, boolean selected) {
		Graphics2D g2 = (Graphics2D) g;
		
		Color c = g2.getColor();

		g2.setColor(penColor);

		Ellipse2D ellipse = new Ellipse2D.Double(leftX, topY, width,
				height);
		if (isFilled){			
		    g2.fill(ellipse);
		}
		else g2.draw(ellipse);
						
		g2.setColor(c);
	}
	
	public void drawOutline(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;

	    // highlight the object, draw with dashes line
		Ellipse2D oval = new Ellipse2D.Double(leftX, topY, width,
				height);

		Stroke oldStroke = g2.getStroke();

		System.out.println("Chaning stroke ...");
		g2.setStroke(dashed);

		g2.draw(oval);

		// set back the old stroke
		g2.setStroke(oldStroke);
		
	}		

	public boolean isInsideSelectionalArea(int X, int Y) {
		if (leftX < X && leftX + width > X && topY < Y && topY + height > Y)
			return true;
		return false;
	}
	
	public void updateShapeInfo(Point p1, Point p2) {
		//construct the rectangle from the points
		double shapeX; //left X, smallest
		double shapeY; //top Y, smallest
		double width;
		double height;
		
		if (p1.getX() <= p2.getX()) {
			shapeX = p1.getX();
			width = p2.getX() - p1.getX() + 1; 
		} else {
			shapeX = p2.getX();
			width = p1.getX() - p2.getX() + 1;
		}
		
		if (p1.getY() <= p2.getY()) {
			shapeY = p1.getY();
			height = p2.getY() - p1.getY() + 1;			
		} else {
			shapeY = p2.getY();
			height = p1.getY() - p2.getY() + 1;
		}
		
		leftX = shapeX;
		topY = shapeY;
		this.width = width;
		this.height = height;
	}
	
	public boolean isInsideBoundaryRectangle(Point p) {
		return isInsideSelectionalArea(p.x, p.y);
	}
	
	public Shape getOutlineShape() {
		//return new RectangleShape(leftX, topY, width, height, penColor);
		return new OvalShape(leftX, topY, width, height, penColor, -1);
	}
	
	public void translate(Point p1, Point p2) {
		leftX += p2.getX() - p1.getX();
		topY += p2.getY() - p1.getY();
	}		
	
	/**
	 * Get control points list: points at 4 corners, clock-wise, starting from leftX, topY
	 * @return
	 */
	protected Vector<Point> getControlPoints() {
		Vector<Point> cl = new Vector<Point>(4, 1);
						
		cl.add(new Point((int)leftX, (int)topY));
		cl.add(new Point((int)(leftX + width), (int)topY));
		cl.add(new Point((int)(leftX + width), (int)(topY + height)));
		cl.add(new Point((int)leftX, (int)(topY + height)));
		return cl;
	}
	
	public ControlPair getControlPoints(Point p) {
		Vector<Point> controlPointList = getControlPoints();
		for (int i = 0; i < controlPointList.size(); i++) {
			if (p.distance(controlPointList.get(i)) < DISTANCE_EPS ) {
				ControlPair cp = new ControlPair(controlPointList.get((i + 2 ) % 4), controlPointList.get(i));
				return cp;
			}
		}
		
		return null;
	}
	
	
	@Override
	public void switchFilling() 
	{
		isFilled = !isFilled;
		
	}
}
